package com.bytz.modules.cms.product.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bytz.common.constant.BooleanConstant;
import com.bytz.common.exception.BytzBootException;
import com.bytz.common.system.query.MPJLambdaWrapperEx;
import com.bytz.common.system.query.MPJQueryGenerator;
import com.bytz.modules.cms.common.util.ExcelUtil;
import com.bytz.modules.cms.product.entity.EcProduct;
import com.bytz.modules.cms.product.entity.Product;
import com.bytz.modules.cms.product.mapper.EcProductMapper;
import com.bytz.modules.cms.product.model.EcProductModel;
import com.bytz.modules.cms.product.service.IEcProductService;
import com.bytz.modules.cms.product.service.IProductService;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 莱宝CMS—产品管理—EC产品导入信息表 服务实现类
 * </p>
 *
 * @author KyleWang
 * @since 2022-10-10
 */
@Service
public class EcProductServiceImpl extends ServiceImpl<EcProductMapper, EcProduct> implements IEcProductService {

    @Autowired
    private IProductService productService;

    @Override
    public Set<String> getByProductNumbers(Collection<String> productNumbers) {

        if (CollectionUtil.isEmpty(productNumbers)) {
            return new HashSet<>();
        }

        return lambdaQuery()
                .select(EcProduct::getProductNumber)
                .in(EcProduct::getProductNumber, productNumbers)
                .list()
                .stream().map(EcProduct::getProductNumber)
                .collect(Collectors.toSet());
    }

    @Override
    public IPage<EcProductModel> queryPage(Page<EcProduct> page, EcProductModel ecProductModel, Map<String, String[]> requestParams) throws Exception {
        MPJLambdaWrapperEx<EcProduct> wrapper = MPJQueryGenerator.initQueryWrapper(ecProductModel, requestParams, EcProduct.class);

        return baseMapper.selectJoinPage(page, EcProductModel.class, wrapper
                .selectAll(EcProduct.class)
                .select(Product::getMaterialDesc)
                .leftJoin(Product.class, on -> on
                        .eq(Product::getProductNumber, EcProductModel::getProductNumber)
                        .eq(Product::getDelFlag, BooleanConstant.INT_FALSE)));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean mergeDb(List<EcProduct> ecProductList) {

        updateProducts(ecProductList.stream().map(EcProduct::getProductNumber).collect(Collectors.toSet()));

        lambdaUpdate().remove();
        return saveBatch(ecProductList);
    }

    @Override
    public void export(HttpServletResponse response) throws IOException {
        ExcelUtil.export("导出订单", EcProduct.class, response, list());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveEcProduct(EcProduct ecProduct) {
        //对传入的ProductNumber进行查询，判断商品编号在product表是否真实存在
        boolean productExists =
                productService.lambdaQuery().eq(Product::getProductNumber, ecProduct.getProductNumber()).exists();
        if (!productExists){
            throw new BytzBootException("商品编号不存在");
        }

        productService.setIsEc(Lists.newArrayList(ecProduct.getProductNumber()), true);

        //save前判断ProductNumber是否已经添加到了受控清单中
        boolean eProductExists =
                lambdaQuery().eq(EcProduct::getProductNumber, ecProduct.getProductNumber()).exists();
        if (eProductExists){
            throw new BytzBootException("不能重复添加同一商品");
        }
        save(ecProduct);
    }

    @Override
    public Boolean removeEcById(String productNumber) {
        productService.setIsEc(Lists.newArrayList(productNumber), false);
        return removeById(productNumber);
    }

    private void updateProducts(Set<String> productNumbers) {

        List<String> currentEcProducts = productService.getEcProducts().stream().map(Product::getProductNumber).collect(Collectors.toList());

        List<String> notEcProducts = new ArrayList<>();

        currentEcProducts.forEach(currentEcProduct -> {
            if (!productNumbers.remove(currentEcProduct)) {
                notEcProducts.add(currentEcProduct);
            }
        });

        productService.setIsEc(productNumbers, true);
        productService.setIsEc(notEcProducts, false);
    }
}
